home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
ColorPicker.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-26
|
18KB
|
729 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "ColorPicker.h"
#include "ET++.h"
#include "ScrollBar.h"
#include "Slider.h"
#include "WindowPort.h"
#include "Window.h"
#include "Buttons.h"
#include "Filler.h"
#include "Look.h"
#include "BorderItems.h"
#include "Fields.h"
#include "Math.h"
#include "PopupItem.h"
#include "OrdColl.h"
#include "CollView.h"
const int cIdValSlider = cIdFirstUser + 1,
cIdRGBSlider = cIdFirstUser + 2,
cIdPicker = cIdFirstUser + 5,
cIdWheel = cIdFirstUser + 7,
cIdReset = cIdFirstUser + 8,
cIdHueNum = cIdFirstUser + 9,
cIdSatNum = cIdFirstUser + 10,
cIdSlider = cIdFirstUser + 11,
cIdNumItem = cIdFirstUser + 12,
cIdPopup = cIdFirstUser + 13,
cIdSetColor = cIdFirstUser + 14;
static ColorPicker *gPicker;
ONEXIT(ColorPicker)
{
SafeDelete(gPicker);
}
//---- ColorCell ---------------------------------------------------------------
class ColorCell: public VObject {
RGBColor *rc;
public:
MetaDef(ColorCell);
ColorCell(RGB c, Point e, bool hfix= TRUE);
ColorCell(RGBColor *c, Point e, bool hfix= TRUE);
~ColorCell();
void DrawAll(Rectangle r, bool highlight);
void SetColor(RGB c)
{ if (rc->SetRGB(&c, MaxWord)) ForceRedraw(); }
RGB GetColor()
{ return RGB(rc->GetRed(), rc->GetGreen(), rc->GetBlue()); }
Command *DoLeftButtonDownCommand(Point, Token t, int);
};
ColorCell::~ColorCell()
{
SafeDelete(rc);
}
ColorCell::ColorCell(RGB c, Point e, bool hfix) : VObject(e)
{
rc= new RGBColor(c);
rc->SetPrec(MaxWord);
SetFlag(eVObjVFixed);
SetFlag(eVObjHFixed, hfix);
}
ColorCell::ColorCell(RGBColor *c, Point e, bool hfix) : VObject(e)
{
rc= c;
rc->SetPrec(MaxWord);
SetFlag(eVObjVFixed);
SetFlag(eVObjHFixed, hfix);
}
//---- DragColor ---------------------------------------------------------------
class DragColor: public Command {
ColorCell *from;
public:
DragColor(ColorCell *f);
void TrackFeedback(Point, Point, bool);
Command *TrackMouse(TrackPhase atp, Point ap, Point, Point np);
};
DragColor::DragColor(ColorCell *f) : Command(123, "Drag Color")
{
from= f;
}
void DragColor::TrackFeedback(Point, Point np, bool)
{
GrLine(from->contentRect.Center(), np);
}
static VObject *drag;
static bool dodrag;
Command *DragColor::TrackMouse(TrackPhase atp, Point, Point, Point np)
{
VObject *v= 0;
Token t((EventCodes)(eEvtPseudo + 300), eFlgNone, np);
Window *w= from->GetWindow();
if (w) {
drag= 0;
dodrag= TRUE;
w->DispatchEvents(t.Pos, t, w);
dodrag= FALSE;
v= drag;
}
if (atp == eTrackRelease) {
if (v) {
if (v == from) {
RGB c= from->GetColor();
from->Control(cIdSetColor, 1, &c);
} else {
fprintf(stderr, "%s\n", v->ClassName());
if (v->IsKindOf(CompositeVObject)) {
ColorCell *cc= new ColorCell(from->GetColor(), Point(20));
v->Add(cc);
v->ExtentChanged(cc);
v->ForceRedraw();
}
}
}
return gNoChanges;
}
return this;
}
//---- CPicker -----------------------------------------------------------------
class CPicker: public Box {
public:
MetaDef(CPicker);
CPicker() : Box(cIdPicker, gPoint1, gPoint0,
(VObjAlign)(eVObjHExpand+eVObjVExpand))
{ }
virtual void SetColor(RGB, bool)
{ }
virtual RGB GetColor()
{ return RGB(0,0,0); }
virtual VObject *DoMakeContent()
{ return 0; }
void SetContainer(VObject *v);
};
NewMetaImpl0(CPicker,Box);
void CPicker::SetContainer(VObject *v)
{
if (Size() <= 0)
Add(new BorderItem(AsString(), DoMakeContent()));
Box::SetContainer(v);
}
//---- ColorSlider -------------------------------------------------------------
class ColorSlider : public VBox {
IntField *num;
Slider *slider;
public:
ColorSlider(int id, char *label);
void SetVal(int val, bool redraw);
void Control(int id, int part, void *val);
int GetVal()
{ return slider->GetMax().y-slider->GetVal().y; }
};
ColorSlider::ColorSlider(int id, char *label)
: VBox(gPoint5, (VObjAlign)(eVObjHCenter+eVObjVExpand))
{
SetId(id);
slider= new Slider(cIdSlider, eVert, TRUE);
slider->SetMax(255, FALSE);
Add(slider);
num= new IntField(cIdNumItem, 0, 0, 255);
Add(new HBox(5, eVObjVBase, new TextItem(label), num, 0));
}
void ColorSlider::SetVal(int val, bool redraw)
{
slider->SetVal(slider->GetMax().y-val, redraw);
num->SetValue(val, redraw);
}
void ColorSlider::Control(int id, int part, void *val)
{
switch (id) {
case cIdSlider:
if (part == eSliderThumb) {
num->SetValue(slider->GetMax().y-slider->GetVal().y, TRUE);
Control(GetId(), eSliderThumb, 0);
}
break;
case cIdNumItem:
if (part == cPartValueChanged) {
slider->SetVal(slider->GetMax().y-num->GetValue(), TRUE);
Control(GetId(), eSliderThumb, 0);
}
break;
default:
VBox::Control(id, part, val);
break;
}
}
//---- ColorCell ---------------------------------------------------------------
NewMetaImpl(ColorCell,VObject, (TP(rc)));
void ColorCell::DrawAll(Rectangle r, bool highlight)
{
if (IsOpen() && r.Clip(contentRect)) {
if (highlight || TestFlag(eVObjHighlight)) {
GrPaintRect(r, gHighlightColor);
GrPaintRect(contentRect.Inset(2), rc);
} else
GrPaintRect(contentRect, rc);
}
}
Command *ColorCell::DoLeftButtonDownCommand(Point, Token, int)
{
return new DragColor(this);
}
//---- ColorWheel --------------------------------------------------------------
static short StdSectors[] = { 36, 36, 18, 18, 1, 0 };
class ColorWheel: public VObject {
protected:
short *sectors;
int circles, maxix, sz;
HSVColor hsv;
RGBColor *palette;
Point border;
ImageCache cache;
public:
MetaDef(ColorWheel);
ColorWheel(int id, short *sectors= StdSectors);
~ColorWheel();
void Draw(Rectangle cr);
Command *DoLeftButtonDownCommand(Point, Token, int);
void SetColor(HSVColor c, bool redraw);
void SetColor2(HSVColor c, bool redraw);
Rectangle DotRect();
HSVColor MapPointToColor(Point p);
Metric GetMinSize()
{ return Metric(245); }
HSVColor GetColor()
{ return hsv; }
};
//---- PickerCommand -----------------------------------------------------------
class PickerCommand: public Command {
ColorWheel *wheel;
public:
PickerCommand(class ColorWheel *w) : Command("pick")
{ wheel= w; }
Command *TrackMouse(TrackPhase, Point ap, Point, Point np);
void TrackFeedback(Point, Point, bool)
{ }
};
Command *PickerCommand::TrackMouse(TrackPhase atp, Point, Point, Point np)
{
wheel->SetColor2(wheel->MapPointToColor(np), TRUE);
if (atp == eTrackRelease)
return gNoChanges;
return this;
}
//---- ColorWheel --------------------------------------------------------------
NewMetaImpl(ColorWheel,VObject, (TV(sectors,circles), T(circles), T(maxix), T(border)));
ColorWheel::ColorWheel(int id, short *sects) : VObject(id)
{
sectors= sects;
for (sz= circles= 0; sectors[circles]; circles++)
sz+= sectors[circles];
border= 6;
palette= new RGBColor[sz];
maxix= 0;
SetColor(HSVColor(0, MaxWord, MaxWord), FALSE);
SetFlag(eVObjHFixed|eVObjVFixed);
}
ColorWheel::~ColorWheel()
{
SafeDelete(palette);
}
HSVColor ColorWheel::MapPointToColor(Point p)
{
HSVColor hc= hsv;
double rad= contentRect.Inset(border).extent.x / 2.0;
hc.hue= contentRect.PointToAngle(p);
hc.saturation= (int) (Length(p - contentRect.Center()) / rad
* (double)MaxWord + 0.5);
return hc;
}
Rectangle ColorWheel::DotRect()
{
Rectangle mark(13), inner= contentRect.Inset(border);
double w= (double) inner.extent.x / (double) MaxWord * hsv.saturation / 2.0,
h= (double) inner.extent.y / (double) MaxWord * hsv.saturation / 2.0;
mark.origin= contentRect.Center()
+ PolarToPoint((double)(hsv.hue), w, h) - mark.extent/2;
return mark;
}
void ColorWheel::SetColor(HSVColor c, bool redraw)
{
if (hsv.hue != c.hue || hsv.saturation != c.saturation) {
if (redraw)
InvalidateRect(DotRect());
hsv.hue= c.hue;
hsv.saturation= Math::Min(c.saturation, (short) MaxWord);
if (redraw)
InvalidateRect(DotRect());
}
if (c.value != hsv.value) {
int i, cir;
bool invalidate= FALSE;
hsv.value= c.value;
for (i= cir= 0; cir < circles; cir++) {
int sat= (MaxWord * (circles-1-cir)) / circles;
for (int h= 0; h < sectors[cir]; h++) {
int hue= (360 * h + (360/sectors[cir]/2)) / sectors[cir];
if (palette[i].SetHSV(hue, sat, hsv.value, MaxWord))
invalidate= TRUE;
i++;
}
}
if (invalidate) {
ForceRedraw();
cache.Invalidate();
}
}
}
void ColorWheel::SetColor2(HSVColor c, bool redraw)
{
if (hsv.hue != c.hue || hsv.saturation != c.saturation) {
SetColor(c, redraw);
Control(GetId(), cPartValueChanged, (void*) &hsv);
}
}
void ColorWheel::Draw(Rectangle cr)
{
if (cache.Open(cr)) {
Rectangle r(contentRect.Inset(border));
Point Step= r.extent/(2*circles-1);
int sat, i;
for (i= sat= 0; sat < circles; sat++) {
for (int hue= 0; hue < sectors[sat]; hue++)
GrPaintWedge(r, 360 * hue / sectors[sat], 360/sectors[sat],
&palette[i++]);
r= r.Inset(Step);
}
GrSetPenNormal();
GrSetPenSize(2);
GrStrokeOval(contentRect.Inset(border));
cache.Close();
}
GrSetPenSize(3);
GrSetPenInk(gInkWhite);
GrStrokeOval(DotRect());
GrSetPenNormal();
GrSetPenInk(gInkBlack);
GrStrokeOval(DotRect().Inset(1));
}
Command *ColorWheel::DoLeftButtonDownCommand(Point, Token, int)
{
return new PickerCommand(this);
}
//---- HSVPicker ---------------------------------------------------------------
class HSVPicker: public CPicker {
ColorSlider *valslider;
ColorWheel *wheel;
IntField *hNum, *sNum;
public:
MetaDef(HSVPicker);
HSVPicker() : CPicker()
{ }
void SetColor(RGB, bool);
void Control(int id, int part, void *val);
RGB GetColor();
char *AsString()
{ return "HSV"; }
VObject *DoMakeContent();
};
NewMetaImpl(HSVPicker,CPicker, (TP(valslider), TP(wheel), TP(hNum), TP(sNum)));
VObject *HSVPicker::DoMakeContent()
{
wheel= new ColorWheel(cIdWheel);
valslider= new ColorSlider(cIdValSlider, "V:");
hNum= new IntField(cIdHueNum, 0, 0, 359);
sNum= new IntField(cIdSatNum, 0, 0, 255);
return new Expander(cIdPicker, eHor, Point(20),
new VBox(5, eVObjVGapExpand,
wheel,
new HBox(10, (VObjAlign)(eVObjVBase+eVObjHGapExpand),
new HBox(5, eVObjVBase, new TextItem("Hue:"), hNum, 0),
new HBox(5, eVObjVBase, new TextItem("Saturation:"), sNum, 0),
0
),
0
),
valslider,
0
);
}
RGB HSVPicker::GetColor()
{
return HSVColor(hNum->GetValue(), sNum->GetValue(), valslider->GetVal());
}
void HSVPicker::SetColor(RGB c, bool redraw)
{
HSVColor hsv(c);
wheel->SetColor(hsv, redraw);
hNum->SetValue(hsv.hue, redraw);
sNum->SetValue(hsv.saturation, redraw);
valslider->SetVal(hsv.value, redraw);
}
void HSVPicker::Control(int id, int part, void *val)
{
switch (id) {
case cIdHueNum:
if (part == cPartValueChanged) {
HSVColor color(hNum->GetValue(), sNum->GetValue(), valslider->GetVal());
wheel->SetColor(color, TRUE);
Control(cIdPicker, cPartValueChanged, 0);
}
break;
case cIdSatNum:
if (part == cPartValueChanged) {
HSVColor color(hNum->GetValue(), sNum->GetValue(), valslider->GetVal());
wheel->SetColor(color, TRUE);
Control(cIdPicker, cPartValueChanged, 0);
}
break;
case cIdValSlider:
if (part == eSliderThumb) {
HSVColor color(hNum->GetValue(), sNum->GetValue(), valslider->GetVal());
wheel->SetColor(color, TRUE);
Control(cIdPicker, cPartValueChanged, 0);
}
break;
case cIdWheel:
if (part == cPartValueChanged) {
HSVColor color(wheel->GetColor());
hNum->SetValue(color.hue, TRUE);
sNum->SetValue(color.saturation, TRUE);
Control(cIdPicker, cPartValueChanged, 0);
}
break;
default:
CPicker::Control(id, part, val);
break;
}
}
//---- RGBPicker ---------------------------------------------------------------
class RGBPicker: public CPicker {
ColorSlider *red, *green, *blue;
public:
MetaDef(RGBPicker);
RGBPicker() : CPicker()
{ }
void SetColor(RGB, bool redraw);
void Control(int id, int part, void *val);
RGB GetColor()
{ return RGB(red->GetVal(), green->GetVal(), blue->GetVal()); }
char *AsString()
{ return "RGB"; }
VObject *DoMakeContent();
};
NewMetaImpl(RGBPicker,CPicker, (TP(red), TP(green), TP(blue)));
VObject *RGBPicker::DoMakeContent()
{
return new Expander(cIdPicker, eHor, Point(20),
red= new ColorSlider(cIdRGBSlider, "R:"),
green= new ColorSlider(cIdRGBSlider, "G:"),
blue= new ColorSlider(cIdRGBSlider, "B:"),
0
);
}
void RGBPicker::Control(int id, int part, void *val)
{
if (id == cIdRGBSlider && part == eSliderThumb)
CPicker::Control(cIdPicker, cPartValueChanged, 0);
else
CPicker::Control(id, part, val);
}
void RGBPicker::SetColor(RGB color, bool redraw)
{
red->SetVal(color.red, redraw);
green->SetVal(color.green, redraw);
blue->SetVal(color.blue, redraw);
}
//---- PalettePicker -----------------------------------------------------------
class PalettePicker: public CPicker {
CollectionView *cv;
RGB c;
public:
MetaDef(PalettePicker);
PalettePicker() : CPicker()
{ }
RGB GetColor();
void SetColor(RGB cc, bool)
{ c= cc; }
VObject *DoMakeContent();
char *AsString()
{ return "Palette"; }
void Control(int id, int part, void *val);
};
NewMetaImpl0(PalettePicker,CPicker);
VObject *PalettePicker::DoMakeContent()
{
OrdCollection *col= new OrdCollection;
for (int i= 0; i < 256; i++)
col->Add(new ColorCell(new RGBColorCell(i), Point(15)));
cv= new CollectionView(this, col, eCVDefault, 16, 16);
cv->SetId(cIdPicker);
cv->SetGap(gPoint1);
return cv;
}
RGB PalettePicker::GetColor()
{
Rectangle s(cv->GetSelection());
ColorCell *cc= (ColorCell*) cv->GetItem(s.origin.x, s.origin.y);
if (cc)
return cc->GetColor();
return c;
}
void PalettePicker::Control(int id, int part, void *val)
{
if (part == cPartCollSelect)
CPicker::Control(cIdPicker, cPartValueChanged, 0);
else
CPicker::Control(id, part, val);
}
//---- MyColors ----------------------------------------------------------------
class MyColors: public HBox {
public:
MyColors() : HBox(gPoint4, eVObjHLeft)
{ }
Command *DoOtherEventCommand(Point p, Token t);
};
Command *MyColors::DoOtherEventCommand(Point p, Token t)
{
if (dodrag) {
drag= this;
} else
HBox::DoOtherEventCommand(p, t);
return gNoChanges;
}
//---- ColorPicker -------------------------------------------------------------
NewMetaImpl(ColorPicker,Dialog, (TP(oldcell), TP(newcell)));
ColorPicker::ColorPicker(char *name) : Dialog(name)
{
current= 0;
pickers= new OrdCollection;
pickers->Add(new PalettePicker);
pickers->Add(new HSVPicker);
pickers->Add(new RGBPicker);
}
void ColorPicker::DoSetup()
{
//newcell->SetColor(color);
//oldcell->SetColor(oldcolor);
}
void ColorPicker::DoSetDefaults()
{
//newcell->SetColor(color);
//oldcell->SetColor(oldcolor);
}
VObject *ColorPicker::DoMakeContent()
{
Iter next(pickers);
CPicker *p;
Menu *m= new Menu("Model", FALSE);
for (int id= 0; p= (CPicker*) next(); id++)
m->AppendItem(p->AsString(), id);
RGB rc(color);
bag= new MyColors;
bag->Add(new ColorCell(RGB(200,0,0), Point(20)));
bag->Add(new ColorCell(RGB(0,200,0), Point(20)));
bag->Add(new ColorCell(RGB(0,0,200), Point(20)));
return
new Matte(
new HExpander(gPoint10,
border= new VExpander(gPoint10,
(CPicker*)pickers->At(current),
//new Scroller(bag= new HBox(gPoint4, eVObjHLeft)),
new BorderItem("My Colors", new Clipper(bag)),
0
),
new VExpander(gPoint10,
new BorderItem("Old/New",
new VBox(gPoint0, (VObjAlign)(eVObjHExpand),
oldcell= new ColorCell(rc, Point(75, 45), FALSE),
newcell= new ColorCell(rc, Point(75, 45), FALSE),
0
)
),
new Filler(gPoint10),
new PopupButton(cIdPopup, current, m),
new Filler(gPoint10),
new ActionButton(cIdReset, "Reset"),
new ActionButton(cIdCancel, "Cancel"),
new ActionButton(cIdYes, "Set Color", TRUE),
0
),
0
)
);
}
void ColorPicker::Control(int id, int part, void *val)
{
CPicker *picker;
switch (id) {
case cIdPopup:
if (part == cPartToggle && current != (int)val) {
SetFirstHandler(0);
current= (int)val;
picker= (CPicker*) pickers->At(current);
if (picker) {
border->SetAt(0, picker);
picker->SetColor(color, FALSE);
}
}
break;
case cIdPicker:
if (part == cPartValueChanged) {
picker= (CPicker*) pickers->At(current);
color= picker->GetColor();
newcell->SetColor(color);
}
break;
case cIdSetColor:
newcell->SetColor(*((RGB*)val));
break;
case cIdReset:
color= oldcolor;
picker= (CPicker*) pickers->At(current);
picker->SetColor(color, TRUE);
newcell->SetColor(color);
id= cIdNone;
break;
case cIdCancel:
color= oldcolor;
break;
}
Dialog::Control(id, part, val);
}
HSVColor ColorPicker::PickColor(HSVColor c)
{
color= c;
oldcolor= c;
Dialog::ShowUnderMouse();
return color;
}
HSVColor PickColor(HSVColor c)
{
if (gPicker == 0)
gPicker= new ColorPicker("Color Picker");
return gPicker->PickColor(c);
}